package com.changzhi.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.changzhi.common.constans.RedisConstans;
import com.changzhi.common.constants.RedisConstants;
import com.changzhi.common.enums.MenuTypeEnum;
import com.changzhi.common.exception.ServiceException;
import com.changzhi.common.mq.MqProducer;
import com.changzhi.ldyl.model.*;
import com.changzhi.mapper.*;
import com.changzhi.service.ActivityService;
import com.changzhi.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description:
 * @author: 小落
 * @date: 2020年11月04日
 */
@Slf4j
@Service
public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> implements ActivityService {

	@Autowired
	private RedisUtil redisUtil;
	@Resource
	private ActivityWalletMapper activityWalletMapper;
	@Resource
	private ActivityPrizeMapper activityPrizeMapper;
	@Resource
	private ActivityTestMapper activityTestMapper;
	@Resource
	private ChatChannelShareRatioConfigMapper chatChannelShareRatioConfigMapper;
	@Resource
	private MenuTypeConfigMapper menuTypeConfigMapper;
	@Resource
	private MenuChannelMappingMapper menuChannelMappingMapper;
	@Autowired
	private MqProducer mqProducer;
	@Value("${spring.profiles.active}")
	private String env;

	@Override
	public Activity getActivity(Integer id) {
		if(id == null){
			throw new ServiceException("活动id不能为空");
		}
		Activity activity = redisUtil.get(RedisConstans.ACTIVITY + id);
		if(activity != null){
			return activity;
		}
		activity = getById(id);
		if(activity == null){
			throw new ServiceException("活动数据不存在--id:" + id);
		}
		redisUtil.set(RedisConstans.ACTIVITY + id, activity, RedisConstans.ONE_DAY);
		return activity;
	}

	@Override
	public ActivityWallet getActivityWalletCache(Integer activityId, String userId) {
		String key = RedisConstans.putRediskey(RedisConstans.WALLET, activityId, userId);
		ActivityWallet wallet = redisUtil.get(key);
		if(wallet != null){
			return wallet;
		}
		LambdaQueryWrapper< ActivityWallet> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(ActivityWallet::getActivityId, activityId).eq(ActivityWallet::getUserId, userId);
		wallet = activityWalletMapper.selectOne(wrapper);
		if (wallet == null) {
			wallet = new ActivityWallet();
			wallet.setUserId(userId);
			wallet.setAmount1(0);
			wallet.setAmount2(0);
			wallet.setNum(0);
		}
		redisUtil.set(key, wallet, RedisConstans.ONE_HOUR);
		return wallet;
	}

	//钱包
	public ActivityWallet getActivityWallet(Integer activityId, String userId){
		LambdaQueryWrapper< ActivityWallet> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(ActivityWallet::getActivityId, activityId).eq(ActivityWallet::getUserId, userId);
		ActivityWallet wallet = activityWalletMapper.selectOne(wrapper);
		if (wallet == null) {
			wallet = new ActivityWallet();
			wallet.setUserId(userId);
			wallet.setAmount1(0);
			wallet.setNum(0);
			wallet.setAmount2(0);
		}
		return wallet;
	}

	//奖品
	public ActivityPrize getPrize(Integer activityId, Integer type){
		LambdaQueryWrapper<ActivityPrize> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(ActivityPrize::getActivityId, activityId).eq(ActivityPrize::getType, type);
		wrapper.last("limit 1");
		return activityPrizeMapper.selectOne(wrapper);
	}

	//奖品列表
	public List<ActivityPrize> getPrizeList(Integer activityId, Integer type){
		LambdaQueryWrapper<ActivityPrize> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(ActivityPrize::getActivityId, activityId).eq(ActivityPrize::getStatus, 1);
		if(type != null){
			wrapper.eq(ActivityPrize::getType, type);
		}
		return activityPrizeMapper.selectList(wrapper);
	}

	@Override
	public Map<Integer, Integer> someGiftIdList(Integer activityId, Integer type) {
		Map<Integer, Integer> map = redisUtil.get(RedisConstans.GODDESS_SOME_GIFT + activityId);
		if(map != null){
			return map;
		}
		map = new HashMap<>();
		List<ActivityPrize> prizeList = getPrizeList(activityId, type);
		for (ActivityPrize activityPrize : prizeList) {
			map.put(activityPrize.getGiftId(), activityPrize.getType());
		}
		redisUtil.set(RedisConstans.GODDESS_SOME_GIFT + activityId, map, RedisConstans.ONE_MONTH);
		return map;
	}

	@Override
	public boolean isPointGift(Integer activityId, Integer giftId) {
		Integer result = (Integer) redisUtil.hget(RedisConstans.ACTIVITY_POINT_GIFT  + "_" + activityId, giftId.toString());
		if(result == null){
			LambdaQueryWrapper<ActivityPrize> wrapper = new LambdaQueryWrapper<>();
			wrapper.select(ActivityPrize::getId);
			wrapper.eq(ActivityPrize::getActivityId, activityId).eq(ActivityPrize::getStatus, 1).eq(ActivityPrize::getGiftId, giftId).lt(ActivityPrize::getType, 10).last("limit 1");
			Integer count = activityPrizeMapper.selectCount(wrapper);
			if(count > 0){
				result = 1;
			} else {
				result = 0;
			}
			redisUtil.hset(RedisConstans.ACTIVITY_POINT_GIFT  + "_" + activityId, giftId.toString(), result, RedisConstans.ONE_DAY);
		}
		return result == 1;
	}

	@Override
	public boolean isTestAccount(String userId) {
		Boolean result = redisUtil.get(RedisConstans.ACTIVITY_TEST_ACCOUNT + userId);
		if(result != null){
			return result;
		}
		result = false;
		LambdaQueryWrapper<ActivityTest> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(ActivityTest::getUserId, userId).last("limit 1");
		Integer count = activityTestMapper.selectCount(wrapper);
		if(count > 0){
			result = true;
		}
		redisUtil.set(RedisConstans.ACTIVITY_TEST_ACCOUNT + userId, result, RedisConstans.ONE_DAY);
		return result;
	}

	@Override
	public boolean isOpenChannel(String channelId){
		//2.判断是否公开厅
		Integer flag = redisUtil.get(RedisConstants.CHANNEL_SHARE_RATIO_CONFIG + channelId);
		if(flag != null){
			return flag == 1 ? true : false;
		}
		boolean result = false;
		LambdaQueryWrapper<ChatChannelShareRatioConfig> shareWrapper = new LambdaQueryWrapper<>();
		shareWrapper.select(ChatChannelShareRatioConfig::getId).eq(ChatChannelShareRatioConfig::getChannelId, channelId).eq(ChatChannelShareRatioConfig::getStatus, 1).last("limit 1");
		ChatChannelShareRatioConfig shareRatioConfig = chatChannelShareRatioConfigMapper.selectOne(shareWrapper);
		if (shareRatioConfig != null) {
			result = true;
		}
		return result;
	}

	@Override
	public List<ActivityPrize> getLottyPrizeList(Integer activityId, Integer minType, Integer maxType) {
		LambdaQueryWrapper<ActivityPrize> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(ActivityPrize::getActivityId, activityId);
		wrapper.ge(ActivityPrize::getType, minType);
		wrapper.le(ActivityPrize::getType, maxType);
		wrapper.orderByDesc(ActivityPrize::getRate);
		List<ActivityPrize> prizeList = activityPrizeMapper.selectList(wrapper);
		prizeList.stream().forEach(t->t.setRate(t.getRate() * 1000));
		return prizeList;
	}

	/**
	 * 抽奖概率，概率不带小数点
	 * @return
	 */
	@Override
	public ActivityPrize randomPrize(List<ActivityPrize> prizes) {
		int sum = prizes.stream().mapToInt(t -> t.getRate().intValue()).sum();
		ActivityPrize prize = null;
		int rate = 0;
		int random = RandomUtil.randomInt(0, sum);
		for (ActivityPrize item : prizes) {
			// 中奖概率
			rate += item.getRate();
			if (random < rate) {
				prize = item;
				break;
			}
		}
		return prize;
	}

	@Override
	public void pushBanner(Integer type, String title, String content, String bgUrl, String linkValue, Long millisecond) {
		Map<String, Object> map = new HashMap<>();
		map.put("title", title);
		map.put("content", content);
		map.put("linkType", type);//1=跳转房间，2=跳转网页
		map.put("bgUrl", bgUrl);
		map.put("linkValue", linkValue);
		map.put("bannerShowTime", millisecond);
		mqProducer.sendPushInfo(JSON.toJSONString(map));
	}


	/**
	 * 根据房间id判断是否为正常模式的房间
	 * @param channelId
	 * @return
	 */
	@Override
	public boolean checkNormalMode(String channelId){
		Integer menuId = 124;
		if(!"prod".equals(env)){
			menuId = 3;
		}
		//查询开黑和娱乐所有二级菜单
		LambdaQueryWrapper<MenuTypeConfig> typeConfigWrapper = new LambdaQueryWrapper<>();
		typeConfigWrapper.select(MenuTypeConfig::getMenuid).in(MenuTypeConfig::getMenuclass, MenuTypeEnum.GAME.getValue(), MenuTypeEnum.YULE.getValue());
		List<MenuTypeConfig> configList = menuTypeConfigMapper.selectList(typeConfigWrapper);
		List<Integer> menuIdList = new ArrayList<>();
		for (MenuTypeConfig config : configList) {
			if(config.getMenuid().equals(menuId)){
				continue;
			}
			menuIdList.add(config.getMenuid());
		}
		LambdaQueryWrapper<MenuChannelMapping> mapConfigWrapper = new LambdaQueryWrapper<>();
		mapConfigWrapper.eq(MenuChannelMapping::getChannelId, channelId).in(MenuChannelMapping::getMenuid, menuIdList).eq(MenuChannelMapping::getStatus, 1).last("limit 1");
		//获取当前二级菜单id
		Integer count = menuChannelMappingMapper.selectCount(mapConfigWrapper);
		if (count != null && count > 0) {
			return true;
		}
		log.info("methodName:checkNormalMode,channelId={},menuIdList={}", channelId, JSON.toJSONString(menuIdList));
		return false;
	}


}
